//用于存储所有的游戏对象实例
const GAME_OBJECTS = [];

//所有游戏对象的基类
export class GameObject {
    constructor() {
        GAME_OBJECTS.push(this);
        // 初始化时间间隔为 0，用于记录两帧之间的时间差
        this.timedelta = 0;
        // 标记该对象是否已经调用过 start 方法，初始值为 false
        this.has_called_start = false;
    }

    // start 方法，只会在对象的生命周期中执行一次
    start() {
    }

    // update 方法，每一帧都会执行一次，但不包括第一帧
    update() {
    }

    // on_destroy 方法，在对象被销毁之前执行
    on_destroy() {
    }

    // destroy 方法，用于销毁当前对象
    destroy() {
        this.on_destroy();

        for (let i in GAME_OBJECTS) {
            if (GAME_OBJECTS[i] === this) {
                GAME_OBJECTS.splice(i, 1);
                break;
            }
        }
    }
}

// 用于存储上一帧的时间戳
let last_timestamp;

// 定义一个名为 step 的函数，它是动画循环的核心函数
const step = (timestamp) => {
    for (let obj of GAME_OBJECTS) {
        if (!obj.has_called_start) {
            obj.has_called_start = true;
            obj.start();
        } else {
            // 如果已经调用过 start 方法，计算当前帧和上一帧之间的时间差
            obj.timedelta = timestamp - last_timestamp;
            // 调用对象的 update 方法，执行每帧更新逻辑
            obj.update();
        }
    }

    // 更新 last_timestamp 为当前帧的时间戳
    last_timestamp = timestamp;

    // 请求浏览器在下一帧调用 step 函数，形成动画循环
    requestAnimationFrame(step);
}

// 首次调用 requestAnimationFrame 启动动画循环
requestAnimationFrame(step);